//
//  ViewController.swift
//  Hermes
//
//  Created by FH on 2021/1/7.
//  Copyright © 2021 Agora. All rights reserved.
//

import Cocoa
import WebKit

// const vars
let constHorizontalMarginDim: Float = 4.0
let constVerticalMarginDim: Float = 4.0
let constScriptsInfoViewHeight: Float = 100
let constSettingsInfoViewHeight: Float = 90
let constLoggerInfoViewHeight: Float = 130
let constLocalStreamPanelDim: Float = 459
let constLocalStreamPanelSmallDim: Float = 300
let constRemoteUsersPanelWidth: Float = 100
let constVideoItemMarginDim: Float = 2
let constRemoteUidHeight: Float = 13

// TODO: 合并到VC中
class MainContext : PropsStatesContext {
    private let localStates = StatesStore()
    fileprivate var isInited = false
    fileprivate var allScriptNames: [String]! = nil
    @PropState
    fileprivate var finishedScriptSettingWithSave: Bool? = nil
    @PropState
    fileprivate var finishedPrivateParamsWithSave: Bool? = nil
    @PropState
    var editScript: ScriptBundles? = nil
    @PropState
    var forSettingScene: Bool? = nil
    
    init() {
        self.bindStates()
    }
    
    fileprivate func setEditScript(_ script: ScriptBundles) {
        self.$editScript.update(value: script, localStates)
    }
    
    func exitScriptSetting(hasSave: Bool) {
        self.$finishedScriptSettingWithSave.update(value: hasSave, localStates)
        self.$finishedPrivateParamsWithSave.update(value: nil, localStates)
    }
    
    func exitPrivateParamsSetting(hasSave: Bool) {
        self.$finishedPrivateParamsWithSave.update(value: hasSave, localStates)
        self.$finishedPrivateParamsWithSave.update(value: nil, localStates)
    }
}

//////////////////////////////// TODO: remove

class MainViewController: NSViewController {
    let appContext = HermesContext()
    let states = MainContext()
    let yoga = FLContext()
    // for SDKVersion
    let lblSDKVersion = FLLabel()
    let selectSDKVersion = NSPopUpButton()
    let btnLoadOtherSDKVersion = NSButton()
    let btnImportSDK = NSButton()
    let btnDiffSDKVersion = NSButton()
    // for ScriptsInfo View
    let selectScripts = NSPopUpButton()
    let btnEditScript = NSButton()
    let btnAddScript = NSButton()
    let btnInvokeSingleInstruction = NSButton()
    let selectInvokeMode = NSPopUpButton()
    let lblRunMode = FLLabel()
    let btnSubmit = NSButton()
    let btnNextStep = NSButton()
    var tblScript: FLTableView<String, VoidRowCell>! = nil
    // for commonSettings View
    let selectChannelProfile = NSPopUpButton()
    let selectClientRole = NSPopUpButton()
    let selectVideoDimension = NSPopUpButton()
    let selectVideoFrameRate = NSPopUpButton()
    let selectAudioProfile = NSPopUpButton()
    let selectAudioScenario = NSPopUpButton()
    let selectTokenType = NSPopUpButton()
    let inputToken = FLInputField()
    let inputGridCount = FLInputField()
    let inputChannelId = FLInputField()
    let inputAppId = FLInputField()
    let inputUserId = FLInputField()
    let chkUseNewJoinChannel = FLCheckbox()
    let chkAutoSubscribeAudio = FLCheckbox()
    let chkAutoSubscribeVudio = FLCheckbox()
    let chkLogFilter = FLCheckbox()
    let btnJoinChannel = NSButton()
    let btnPrivateParamsBefore = NSButton()
    let btnPrivateParamsAfter = NSButton()
    let btnSettingsParams = NSButton()
    let btnCustomAction = NSButton()
    let scrollCustomButtons: NSScrollView! = nil
    // for stream Views
    let localStreamPanel = LocalStreamComponent()
    let remoteUsersPanel = RemoteUsersComponent()
    let remoteStreamsPanel = RemoteStreamsComponent()
    let loggerPanel = LoggerComponent()
    // present viewcontrollers
    var vcConfigScript: ConfigScriptViewController! = nil
    var vcConfigPrivateParams: ConfigPrivateParamsViewController! = nil
   
    override func loadView() {        
        self.view = NSView(frame: CGRect(x: 0, y: 0, width: 1440, height: 808))
    }
    
    override func viewDidLayout() {
        if !states.isInited, let window = self.view.window {
            window.styleMask.remove(.fullSizeContentView)
            window.styleMask.remove(.resizable)
            // window.titleVisibility = .hidden
            window.title = "Hermes Mac"
            window.isMovableByWindowBackground = true
            let size = self.view.bounds.size
            window.setContentSize(CGSize(width: size.width, height: size.height))
            window.center()
            states.isInited = true
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.dataBinding()
        self.layoutViews()
    }
    
    func dataBinding() {
        // for sdkVersion info
        self.lblSDKVersion.flText = appContext.sdkVersion
        self.selectSDKVersion.addItems(withTitles: [appContext.sdkVersion])
        // for script info
//        states.allScriptNames = ScriptBundles.allScriptNames
        self.selectScripts.addItems(withTitles: states.allScriptNames)
        self.selectInvokeMode.addItems(withTitles: ScriptsInvokeMode.allCaseDescriptions)
        self.lblRunMode.flText = appContext.scriptsInvoker.runningMode.rawValue
        self.btnNextStep.isEnabled = false
        // for common settings
        self.selectChannelProfile.addItems(withTitles: getCaseItemDescriptions(by: "AgoraChannelProfile", appContext.engine))
        // TODO: 需要设置与channelProfile的联动
        self.selectClientRole.addItems(withTitles: getCaseItemDescriptions(by: "AgoraClientRole", appContext.engine))
        self.selectVideoDimension.addItems(withTitles: AppVideoDimension.allCaseDescriptions)
        self.selectVideoFrameRate.addItems(withTitles: getCaseItemDescriptions(by: "AgoraVideoFrameRate", appContext.engine))
        self.selectAudioProfile.addItems(withTitles: getCaseItemDescriptions(by: "AgoraAudioProfile", appContext.engine))
        self.selectAudioScenario.addItems(withTitles: getCaseItemDescriptions(by: "AgoraAudioScenario", appContext.engine))
        self.selectTokenType.addItems(withTitles: AppTokenType.allCaseDescriptions)
        // for buttons
        self.btnAddScript.rac_eventTouch.subscribeNext {[weak self] _ in
            if let self = self {
                self.vcConfigScript = ConfigScriptViewController(self.states)
                self.presentAsModalWindow(self.vcConfigScript)
            }
        }
        
        self.btnPrivateParamsBefore.rac_eventTouch.subscribeNext {[weak self] _ in
            if let self = self {
                self.vcConfigPrivateParams = ConfigPrivateParamsViewController(self.states, forAfter: false)
                self.presentAsModalWindow(self.vcConfigPrivateParams)
            }
        }
        self.btnPrivateParamsAfter.rac_eventTouch.subscribeNext {[weak self] _ in
            if let self = self {
                self.vcConfigPrivateParams = ConfigPrivateParamsViewController(self.states, forAfter: true)
                self.presentAsModalWindow(self.vcConfigPrivateParams)
            }
        }
        
        // for states
        states.$finishedScriptSettingWithSave.signal().ignoreNilValue().subscribeNext {[weak self] hasSave in
            if let self = self {
                if hasSave! {
                    
                }
                self.dismissViewController(self.vcConfigScript)
                self.vcConfigScript = nil
            }
        }
        
        states.$finishedPrivateParamsWithSave.signal().ignoreNilValue().subscribeNext {[weak self] hasSave in
            if let self = self {
                if hasSave! {
                    
                }
                self.dismissViewController(self.vcConfigPrivateParams)
                self.vcConfigPrivateParams = nil
            }
        }
    }

    func layoutViews() {
        self.view.bindAsRoot(to: yoga)

        self.buildSDKVersionAndScriptsInfoView()
        self.buildCommonSettingsView()
        self.buildStreamsGridView()
        self.buildLoggerView()
        
        yoga.apply()
        // load tracing html
        if let tracingFile = Bundle.main.url(forResource: "tracing", withExtension: "html") {
            let webview = WKWebView(frame: CGRect(x: 0, y: 0, width: 5, height: 5))
            webview.wantsLayer = true
            webview.flBackgroundColor = .brown
            self.view.addSubview(webview)
            let request = URLRequest(url: tracingFile)
            webview.load(request)
        }
    }
}
